package com.engine.kq.cmd.dutyrules;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.biz.SimpleBizLogger;
import com.engine.common.constant.BizLogSmallType4Hrm;
import com.engine.common.constant.BizLogType;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.kq.biz.KQDutyRulesBiz;
import com.engine.kq.log.KQLog;
import com.google.common.collect.Lists;
import weaver.common.DateUtil;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 加班规则--新建
 */
public class AddDutyRulesCmd extends AbstractCommonCommand<Map<String, Object>> {

    private SimpleBizLogger logger;

    public AddDutyRulesCmd(Map<String, Object> params, User user) {
        this.user = user;
        this.params = params;
        this.logger = new SimpleBizLogger();

        String name = Util.null2String(params.get("name"));
        BizLogContext bizLogContext = new BizLogContext();
        bizLogContext.setLogType(BizLogType.HRM_ENGINE);//模块类型
        bizLogContext.setBelongType(BizLogSmallType4Hrm.HRM_ENGINE_KQ_OVERTIMERULES);//所属大类型
        bizLogContext.setLogSmallType(BizLogSmallType4Hrm.HRM_ENGINE_KQ_OVERTIMERULES);//当前小类型
        bizLogContext.setParams(params);//当前request请求参数
        logger.setUser(user);//当前操作人
        String mainSql = "select * from kq_dutyRules where name like '%" + name + "%'";
        logger.setMainSql(mainSql, "id");//主表sql
        logger.setMainPrimarykey("id");//主日志表唯一key
        logger.setMainTargetNameColumn("name");

        SimpleBizLogger.SubLogInfo subLogInfo = logger.getNewSubLogInfo();
        String subSql = "select * from kq_dutyRulesDetail where ruleId in (select id from kq_dutyRules where name like '%" + name + "%') order by id";
        subLogInfo.setSubSql(subSql, "id");
        logger.addSubLogInfo(subLogInfo);
        logger.before(bizLogContext);
    }

    @Override
    public BizLogContext getLogContext() {
        return null;
    }

    @Override
    public List<BizLogContext> getLogContexts() {
        return logger.getBizLogContexts();
    }

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            boolean canAdd = HrmUserVarify.checkUserRight("KQOvertimeRulesAdd:Add", user);//是否具有新建权限
            if (!canAdd) {
                resultMap.put("status", "-1");
                resultMap.put("message", SystemEnv.getHtmlLabelName(2012, user.getLanguage()));
                return resultMap;
            }

            /*加班规则名称*/
            String name = Util.null2String(params.get("name"));
            /*考勤组的ID*/
            String groupIds = Util.null2String(params.get("groupIds"));

            /*工作日是否允许加班：0-不允许、1-允许*/
            int dutyEnable2 = Util.getIntValue((String) params.get("dutyEnable2"), 1);
            /*工作日的加班方式：1-需审批，以审批单为准、2-需审批，以打卡为准，但是不能超过审批时长、3-无需审批，根据打卡时间计算加班时长*/
            int computingMode2 = Util.getIntValue((String) params.get("computingMode2"), 1);
            /*工作日下班多少分钟后开始计算加班*/
            int startTime2 = Util.getIntValue((String) params.get("startTime2"), 30);
            /*工作日最小加班时长*/
            int minimumLen2 = Util.getIntValue((String) params.get("minimumLen2"), 30);
            /*工作日是否允许加班转调休*/
            int paidLeaveEnable2 = Util.getIntValue((String) params.get("paidLeaveEnable2"), 0);
            /*工作日加班转调休比例中的加班时长*/
            double lenOfDuty2 = Util.getDoubleValue((String) params.get("lenOfDuty2"), 30.0);
            /*工作日加班转调休比例中的调休时长*/
            double lenOfLeave2 = Util.getDoubleValue((String) params.get("lenOfLeave2"), 30.0);

            /*休息日是否允许加班：0-不允许、1-允许*/
            int dutyEnable3 = Util.getIntValue((String) params.get("dutyEnable3"), 1);
            /*休息日的加班方式：1-需审批，以审批单为准、2-需审批，以打卡为准，但是不能超过审批时长、3-无需审批，根据打卡时间计算加班时长*/
            int computingMode3 = Util.getIntValue((String) params.get("computingMode3"), 1);
            /*休息日的最小加班时长*/
            int minimumLen3 = Util.getIntValue((String) params.get("minimumLen3"), 30);
            /*休息日是否允许加班转调休*/
            int paidLeaveEnable3 = Util.getIntValue((String) params.get("paidLeaveEnable3"), 0);
            /*休息日加班转调休比例中的加班时长*/
            double lenOfDuty3 = Util.getDoubleValue((String) params.get("lenOfDuty3"), 30.0);
            /*休息日加班转调休比例中的调休时长*/
            double lenOfLeave3 = Util.getDoubleValue((String) params.get("lenOfLeave3"), 30.0);
            /*休息日是否有休息时间*/
            int hasRestTime3 = Util.getIntValue((String) params.get("hasRestTime3"), 0);

            /*节假日是否允许加班：0-不允许、1-允许*/
            int dutyEnable1 = Util.getIntValue((String) params.get("dutyEnable1"), 1);
            /*节假日的加班方式：1-需审批，以审批单为准、2-需审批，以打卡为准，但是不能超过审批时长、3-无需审批，根据打卡时间计算加班时长*/
            int computingMode1 = Util.getIntValue((String) params.get("computingMode1"), 1);
            /*节假日的最小加班时长*/
            int minimumLen1 = Util.getIntValue((String) params.get("minimumLen1"), 30);
            /*节假日是否允许加班转调休*/
            int paidLeaveEnable1 = Util.getIntValue((String) params.get("paidLeaveEnable1"), 0);
            /*节假日加班转调休比例中的加班时长*/
            double lenOfDuty1 = Util.getDoubleValue((String) params.get("lenOfDuty1"), 30.0);
            /*假节日加班转调休比例中的调休时长*/
            double lenOfLeave1 = Util.getDoubleValue((String) params.get("lenOfLeave1"), 30.0);
            /*节假日是否有休息时间*/
            int hasRestTime1 = Util.getIntValue((String) params.get("hasRestTime1"), 0);
            if(computingMode2 == 4 || computingMode1 == 4 || computingMode3 == 4 ){
              //如果是流程和打卡取交集的话，加班单位不能是下拉框半天或者整天
              int minimumUnit = KQDutyRulesBiz.getMinimumUnit();
              if(minimumUnit == 2 || minimumUnit == 4){
                resultMap.put("sign", "-1");
                resultMap.put("message", SystemEnv.getHtmlLabelName(529168, user.getLanguage()));
                return resultMap;
              }
            }
          KQLog kqLog = new KQLog();
          kqLog.info("AddDutyRulesCmd:params:"+params);

            /*获取今天的日期*/
            Calendar today = Calendar.getInstance();
            String currentDate = Util.add0(today.get(Calendar.YEAR), 4) + "-"
                    + Util.add0(today.get(Calendar.MONTH) + 1, 2) + "-"
                    + Util.add0(today.get(Calendar.DAY_OF_MONTH), 2);
            String tomorrowDate = DateUtil.addDate(currentDate, 1);

            //顺序显示，2是工作日，3是休息日，1是节假日
            int[] changetype = {2,3,1};

            boolean flag = false;//是否保存成功

            String sql = "insert into kq_DutyRules(name,groupIds,isDelete) values(?,?,0)";
            RecordSet recordSet = new RecordSet();
            RecordSet recordSet1 = new RecordSet();
            flag = recordSet.executeUpdate(sql, name, groupIds);
            if (!flag) {
              resultMap.put("sign", "-1");
              resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
              return resultMap;
            }

            int ruleId = 0;//刚刚插入的数据的ID
            sql = "select max(id) maxId from kq_DutyRules";
            recordSet.executeQuery(sql);
            if (recordSet.next()) {
              ruleId = recordSet.getInt("maxId");
            }

            List<String> rulesdetailidList = Lists.newArrayList();

            String[] fields = new String[]{"dutyEnable","computingMode","startTime","minimumLen",
                "paidLeaveEnable","lenOfDuty","lenOfLeave","hasRestTime","before_startTime",
                "has_cut_point","cut_point","paidLeaveEnableType","paidLeaveEnableDefaultType",
                "paidLeaveEnableFlowType","restTimeType"};
            String str_fields = Arrays.asList(fields).stream().collect(Collectors.joining(","));
            String split_str = Arrays.asList(fields).stream().map(s -> {return "?";}).collect(Collectors.joining(","));
            for(int i = 0 ; i < changetype.length ; i++) {
              int changetype_index = changetype[i];
              sql = "insert into kq_DutyRulesDetail(ruleId,dayType,"+str_fields+") " +
                  "values(?,?,"+split_str+")";
              String value_str = "";
              int size = 2+fields.length;
              Object[] objects = new Object[size];
              objects[0] = ruleId;
              objects[1] = changetype_index;
              for(int j = 0 ; j < fields.length ;j++){
                String _key = fields[j]+changetype_index;
                String _value = Util.null2String(params.get(_key));
                if("before_startTime".equalsIgnoreCase(fields[j])){
                  _value = Util.null2s(Util.null2String(params.get(_key)),"0");
                }
                if("startTime".equalsIgnoreCase(fields[j])){
                  _value = Util.null2s(Util.null2String(params.get(_key)),"0");
                }
                value_str += ","+_value;
                objects[2+j] = _value;
              }
              if(value_str.length() > 0){
                flag = recordSet.executeUpdate(sql, objects);
                if(flag){

                  int rulesdetailid = 0;//刚刚插入的明细数据的ID
                  sql = "select max(id) maxId from kq_DutyRulesDetail";
                  recordSet.executeQuery(sql);
                  if (recordSet.next()) {
                    rulesdetailid = recordSet.getInt("maxId");
                  }
                  rulesdetailidList.add(rulesdetailid+"");

                  String hasRestTime_key = "hasRestTime"+changetype_index;
                  String hasRestTime_value = Util.null2String(params.get(hasRestTime_key));
                  if("1".equalsIgnoreCase(hasRestTime_value)){
                    List<String> restIds = Lists.newArrayList();
                    String restTimeType_key = "restTimeType"+changetype_index;
                    String restTimeType_value = Util.null2String(params.get(restTimeType_key));

                    String restTimeRule_key = "restTimeRule"+changetype_index;
                    String restTimeRule_value = Util.null2String(params.get(restTimeRule_key));
                    if(restTimeRule_value.length() > 0){
                      JSONArray jsonArray = JSONArray.parseArray(restTimeRule_value);
                      if("1".equalsIgnoreCase(restTimeType_value)){
                        for(int k = 0 ; k < jsonArray.size() ; k++){
                          JSONObject jsonObject = (JSONObject) jsonArray.get(k);
                          String startType = "0";
                          String endType = "0";
                          String startTime = Util.null2String(jsonObject.get("startTime"));
                          String endTime = Util.null2String(jsonObject.get("endTime"));
                          String restTimeSql = "insert into kq_DutyRestTime(ruleId,dayType,startType,startTime,endType,endTime) values(?,?,?,?,?,?)";
                          flag = recordSet.executeUpdate(restTimeSql, ruleId, changetype_index, startType, startTime, endType, endTime);
                          if (flag) {
                            int restId = 0;
                            String restSql = "select max(id) maxId from kq_DutyRestTime";
                            recordSet1.executeQuery(restSql);
                            if (recordSet1.next()) {
                              restId = recordSet1.getInt("maxId");
                              restIds.add(""+restId);
                            }
                            resultMap.put("sign", "1");
                            resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功
                          } else {
                            if(!rulesdetailidList.isEmpty()){
                              delFail(rulesdetailidList,restIds,ruleId);
                            }
                            resultMap.put("sign", "-1");
                            resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
                            return resultMap;
                          }
                        }
                      }else if("2".equalsIgnoreCase(restTimeType_value)){
                        for(int k = 0 ; k < jsonArray.size() ; k++){
                          JSONObject jsonObject = (JSONObject) jsonArray.get(k);
                          String duty = Util.null2String(jsonObject.get("duty"));
                          String exclude = Util.null2String(jsonObject.get("exclude"));
                          String restTimeSql = "insert into kq_DutyRestlength(ruleId,dayType,overlength,cutlength,dsporder) values(?,?,?,?,?)";
                          flag = recordSet.executeUpdate(restTimeSql, ruleId, changetype_index, duty, exclude, k);
                          if (flag) {
                            int restId = 0;
                            String restSql = "select max(id) maxId from kq_DutyRestlength";
                            recordSet1.executeQuery(restSql);
                            if (recordSet1.next()) {
                              restId = recordSet1.getInt("maxId");
                              restIds.add(""+restId);
                            }
                            resultMap.put("sign", "1");
                            resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功
                          } else {
                            if(!rulesdetailidList.isEmpty()){
                              delFail(rulesdetailidList, restIds, ruleId);
                            }
                            resultMap.put("sign", "-1");
                            resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
                            return resultMap;
                          }
                        }
                      }
                    }
                  }
                  String paidLeaveEnableType_key = "paidLeaveEnableType"+changetype_index;
                  String paidLeaveEnableType_value = Util.null2String(params.get(paidLeaveEnableType_key));

                  String paidLeaveEnableTypeRule_key = "paidLeaveEnableTypeRule"+changetype_index;
                  String paidLeaveEnableTypeRule_value = Util.null2String(params.get(paidLeaveEnableTypeRule_key));
                  if("1".equalsIgnoreCase(paidLeaveEnableType_value)){
                    String paidLeaveEnableDefaultType_key = "paidLeaveEnableDefaultType"+changetype_index;
                    String paidLeaveEnableDefaultType_value = Util.null2String(params.get(paidLeaveEnableDefaultType_key));
                    if("2".equalsIgnoreCase(paidLeaveEnableDefaultType_value)){
//                  按加班时长范围设置转调休时长
                      JSONArray jsonArray = JSONArray.parseArray(paidLeaveEnableTypeRule_value);
                      for(int k = 0 ; k < jsonArray.size() ; k++){
                        JSONObject jsonObject = (JSONObject) jsonArray.get(k);
                        String work = Util.null2String(jsonObject.get("work"));
                        String rest = Util.null2String(jsonObject.get("rest"));
                        String detailsql = "insert into kq_DutyBalanceLengthDetail(rulesdetailid,dutylength,balancelength,dsporder) values(?,?,?,?)";
                        flag = recordSet.executeUpdate(detailsql, rulesdetailid, work, rest, k);
                        if (flag) {
                          resultMap.put("sign", "1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功
                        } else {
                          if(!rulesdetailidList.isEmpty()){
                            delFail(rulesdetailidList, null, ruleId);
                          }
                          resultMap.put("sign", "-1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
                          return resultMap;
                        }
                      }
                    }else if("3".equalsIgnoreCase(paidLeaveEnableDefaultType_value)){
//                  按加班的时间段设置转调休时长
                      JSONArray jsonArray = JSONArray.parseArray(paidLeaveEnableTypeRule_value);
                      for(int k = 0 ; k < jsonArray.size() ; k++){
                        JSONObject jsonObject = (JSONObject) jsonArray.get(k);
                        String time = Util.null2String(jsonObject.get("time"));
                        String left = Util.null2String(jsonObject.get("left"));
                        String right = Util.null2String(jsonObject.get("right"));
                        String detailsql = "insert into kq_DutyBalanceTimeDetail(rulesdetailid,timepoint,lenOfDuty,lenOfLeave,dsporder) values(?,?,?,?,?)";
                        flag = recordSet.executeUpdate(detailsql, rulesdetailid, time, left, right,k);
                        if (flag) {
                          resultMap.put("sign", "1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功
                        } else {
                          if(!rulesdetailidList.isEmpty()){
                            delFail(rulesdetailidList, null, ruleId);
                          }
                          resultMap.put("sign", "-1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
                          return resultMap;
                        }
                      }
                    }
                  }else if("2".equalsIgnoreCase(paidLeaveEnableType_value)){
                    String paidLeaveEnableFlowType_key = "paidLeaveEnableFlowType"+changetype_index;
                    String paidLeaveEnableFlowType_value = Util.null2String(params.get(paidLeaveEnableFlowType_key));
                    if("2".equalsIgnoreCase(paidLeaveEnableFlowType_value)){
//                  按加班时长范围设置转调休时长
                      JSONArray jsonArray = JSONArray.parseArray(paidLeaveEnableTypeRule_value);
                      for(int k = 0 ; k < jsonArray.size() ; k++){
                        JSONObject jsonObject = (JSONObject) jsonArray.get(k);
                        String work = Util.null2String(jsonObject.get("work"));
                        String rest = Util.null2String(jsonObject.get("rest"));
                        String detailsql = "insert into kq_DutyBalanceLengthDetail(rulesdetailid,dutylength,balancelength,dsporder) values(?,?,?,?)";
                        flag = recordSet.executeUpdate(detailsql, rulesdetailid, work, rest, k);
                        if (flag) {
                          resultMap.put("sign", "1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功
                        } else {
                          if(!rulesdetailidList.isEmpty()){
                            delFail(rulesdetailidList, null, ruleId);
                          }
                          resultMap.put("sign", "-1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
                          return resultMap;
                        }
                      }
                    }else if("3".equalsIgnoreCase(paidLeaveEnableFlowType_value)){
//                  按加班的时间段设置转调休时长
                      JSONArray jsonArray = JSONArray.parseArray(paidLeaveEnableTypeRule_value);
                      for(int k = 0 ; k < jsonArray.size() ; k++){
                        JSONObject jsonObject = (JSONObject) jsonArray.get(k);
                        String time = Util.null2String(jsonObject.get("time"));
                        String left = Util.null2String(jsonObject.get("left"));
                        String right = Util.null2String(jsonObject.get("right"));
                        String detailsql = "insert into kq_DutyBalanceTimeDetail(rulesdetailid,timepoint,lenOfDuty,lenOfLeave,dsporder) values(?,?,?,?,?)";
                        flag = recordSet.executeUpdate(detailsql, rulesdetailid, time, left, right,k);
                        if (flag) {
                          resultMap.put("sign", "1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功
                        } else {
                          if(!rulesdetailidList.isEmpty()){
                            delFail(rulesdetailidList, null, ruleId);
                          }
                          resultMap.put("sign", "-1");
                          resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
                          return resultMap;
                        }
                      }
                    }
                  }
                }else{
                  if(!rulesdetailidList.isEmpty()){
                    delFail(rulesdetailidList, null, ruleId);
                  }
                  resultMap.put("sign", "-1");
                  resultMap.put("message", SystemEnv.getHtmlLabelName(84544, user.getLanguage()));//保存失败
                  return resultMap;
                }
              }
            }

          resultMap.put("sign", "1");
          resultMap.put("message", SystemEnv.getHtmlLabelName(83551, user.getLanguage()));//保存成功

        } catch (Exception e) {
            resultMap.put("sign", "-1");
            resultMap.put("message", SystemEnv.getHtmlLabelName(382661, user.getLanguage()));
            writeLog(e);
        }
        return resultMap;
    }

  /**
   * 保存失败时候把错误数据删除
   * @param rulesdetailidList
   * @param restIds
   * @param ruleId
   */
  public void delFail(List<String> rulesdetailidList, List<String> restIds, int ruleId){
    RecordSet rs = new RecordSet();
    String delSql1 = "delete from kq_DutyRules where id = ? ";
    rs.executeUpdate(delSql1, ruleId);

    for(String rulesdetailid : rulesdetailidList){
      String delSql = "delete from kq_dutyrulesdetail where id = ? ";
      rs.executeUpdate(delSql,rulesdetailid);
    }
    if(restIds != null && !restIds.isEmpty()){
      for(String restId : restIds){
        String delSql = "delete from kq_dutyresttime where id = ? ";
        rs.executeUpdate(delSql,restId);
        delSql = "delete from kq_dutyrestlength where id = ? ";
        rs.executeUpdate(delSql,restId);
      }
    }
  }
}
